<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>ActionDispatch::RemoteIp</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" href="../../css/reset.css" type="text/css" media="screen" />
<link rel="stylesheet" href="../../css/main.css" type="text/css" media="screen" />
<link rel="stylesheet" href="../../css/github.css" type="text/css" media="screen" />
<script src="../../js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../../js/jquery-effect.js" type="text/javascript" charset="utf-8"></script>
<script src="../../js/main.js" type="text/javascript" charset="utf-8"></script>
<script src="../../js/highlight.pack.js" type="text/javascript" charset="utf-8"></script>

</head>

<body>     
    <div class="banner">
        
            <span>Ruby on Rails v4.0.0</span><br />
        
        <h1>
            <span class="type">Class</span> 
            ActionDispatch::RemoteIp 
            
                <span class="parent">&lt; 
                    
                    <a href="../Object.html">Object</a>
                    
                </span>
            
        </h1>
        <ul class="files">
            
            <li><a href="../../files/actionpack/lib/action_dispatch/middleware/remote_ip_rb.html">actionpack/lib/action_dispatch/middleware/remote_ip.rb</a></li>
            
        </ul>
    </div>
    <div id="bodyContent">
        <div id="content">
  
    <div class="description">
      
<p>This middleware calculates the IP address of the remote client that is
making the request. It does this by checking various headers that could
contain the address, and then picking the last-set address that is not on
the list of trusted IPs. This follows the precedent set by e.g. <a
href="https://issues.apache.org/bugzilla/show_bug.cgi?id=50453">the Tomcat
server</a>, with <a
href="http://blog.gingerlime.com/2012/rails-ip-spoofing-vulnerabilities-and-protection">reasoning
explained at length</a> by @gingerlime. A more detailed explanation of the
algorithm is given at <a
href="RemoteIp/GetIp.html#method-i-calculate_ip">ActionDispatch::RemoteIp::GetIp#calculate_ip</a>.</p>

<p>Some Rack servers concatenate repeated headers, like <a
href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2">HTTP
RFC 2616</a> requires. Some Rack servers simply drop preceding headers, and
only report the value that was <a
href="http://andre.arko.net/2011/12/26/repeated-headers-and-ruby-web-servers">given
in the last header</a>. If you are behind multiple proxy servers (like
Nginx to HAProxy to Unicorn) then you should test your Rack server to make
sure your data is good.</p>

<p>IF YOU DON’T USE A PROXY, THIS MAKES YOU VULNERABLE TO IP SPOOFING. This
middleware assumes that there is at least one proxy sitting around and
setting headers with the client’s remote IP address. If you don’t use a
proxy, because you are hosted on e.g. Heroku without <a
href="SSL.html">SSL</a>, any client can claim to have any IP address by
setting the X-Forwarded-For header. If you care about that, then you need
to explicitly drop or ignore those headers sometime before this middleware
runs.</p>

    </div>
  


  


  
  


  
    <!-- Namespace -->
    <div class="sectiontitle">Namespace</div>
    <ul>
      
        <li>
          <span class="type">CLASS</span>
          <a href="RemoteIp/GetIp.html">ActionDispatch::RemoteIp::GetIp</a>
        </li>
      
        <li>
          <span class="type">CLASS</span>
          <a href="RemoteIp/IpSpoofAttackError.html">ActionDispatch::RemoteIp::IpSpoofAttackError</a>
        </li>
      
    </ul>
  


  
    <!-- Method ref -->
    <div class="sectiontitle">Methods</div>
    <dl class="methods">
      
        <dt>C</dt>
        <dd>
          <ul>
            
              
              <li>
                <a href="RemoteIp.html#method-i-call">call</a>
              </li>
            
          </ul>
        </dd>
      
        <dt>N</dt>
        <dd>
          <ul>
            
              
              <li>
                <a href="RemoteIp.html#method-c-new">new</a>
              </li>
            
          </ul>
        </dd>
      
    </dl>
  

  



  

    

    

    
      <!-- Section constants -->
      <div class="sectiontitle">Constants</div>
      <table border='0' cellpadding='5'>
        
          <tr valign='top'>
            <td class="attr-name">TRUSTED_PROXIES</td>
            <td>=</td>
            <td class="attr-value">%r{
^127\.0\.0\.1$                | # localhost IPv4
^::1$                         | # localhost IPv6
^fc00:                        | # private IPv6 range fc00
^10\.                         | # private IPv4 range 10.x.x.x
^172\.(1[6-9]|2[0-9]|3[0-1])\.| # private IPv4 range 172.16.0.0 .. 172.31.255.255
^192\.168\.                     # private IPv4 range 192.168.x.x
}x</td>
          </tr>
          
            <tr valign='top'>
              <td>&nbsp;</td>
              <td colspan="2" class="attr-desc"><p>The default trusted IPs list simply includes IP addresses that are
guaranteed by the IP specification to be private addresses. Those will not
be the ultimate client IP in production, and so are discarded. See <a
href="http://en.wikipedia.org/wiki/Private_network">en.wikipedia.org/wiki/Private_network</a>
for details.</p></td>
            </tr>
          
        
      </table>
    


    
      <!-- Section attributes -->
      <div class="sectiontitle">Attributes</div>
      <table border='0' cellpadding='5'>
        
          <tr valign='top'>
            <td class='attr-rw'>
              [R]
            </td>
            <td class='attr-name'>check_ip</td>
            <td class='attr-desc'></td>
          </tr>
        
          <tr valign='top'>
            <td class='attr-rw'>
              [R]
            </td>
            <td class='attr-name'>proxies</td>
            <td class='attr-desc'></td>
          </tr>
        
      </table>
    


    <!-- Methods -->
    
      <div class="sectiontitle">Class Public methods</div>
      
        <div class="method">
          <div class="title method-title" id="method-c-new">
            
              <b>new</b>(app, check_ip_spoofing = true, custom_proxies = nil)
            
            <a href="RemoteIp.html#method-c-new" name="method-c-new" class="permalink">Link</a>
          </div>
          
          
            <div class="description">
              <p>Create a new <code>RemoteIp</code> middleware instance.</p>

<p>The <code>check_ip_spoofing</code> option is on by default. When on, an
exception is raised if it looks like the client is trying to lie about its
own IP address. It makes sense to turn off this check on sites aimed at
non-IP clients (like WAP devices), or behind proxies that set headers in an
incorrect or confusing way (like AWS ELB).</p>

<p>The <code>custom_trusted</code> argument can take a regex, which will be
used instead of <code>TRUSTED_PROXIES</code>, or a string, which will be
used in addition to <code>TRUSTED_PROXIES</code>. Any proxy setup will put
the value you want in the middle (or at the beginning) of the
X-Forwarded-For list, with your proxy servers after it. If your proxies
aren’t removed, pass them in via the <code>custom_trusted</code> parameter.
That way, the middleware will ignore those IP addresses, and return the one
that you want.</p>
            </div>
          
          
          
          
          
            
            <div class="sourcecode">
              
              <p class="source-link">
                Source: 
                <a href="javascript:toggleSource('method-c-new_source')" id="l_method-c-new_source">show</a>
                
                  | <a href="https://github.com/rails/rails/blob/a8df5bdc5d3cd5ad21758d8e421130bc9518b1dd/actionpack/lib/action_dispatch/middleware/remote_ip.rb#L57" target="_blank" class="github_url">on GitHub</a>
                
              </p>
              <div id="method-c-new_source" class="dyn-source">
                <pre><span class="ruby-comment"># File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 57</span>
<span class="ruby-keyword">def</span> <span class="ruby-keyword ruby-title">initialize</span>(<span class="ruby-identifier">app</span>, <span class="ruby-identifier">check_ip_spoofing</span> = <span class="ruby-keyword">true</span>, <span class="ruby-identifier">custom_proxies</span> = <span class="ruby-keyword">nil</span>)
  <span class="ruby-ivar">@app</span> = <span class="ruby-identifier">app</span>
  <span class="ruby-ivar">@check_ip</span> = <span class="ruby-identifier">check_ip_spoofing</span>
  <span class="ruby-ivar">@proxies</span> = <span class="ruby-keyword">case</span> <span class="ruby-identifier">custom_proxies</span>
    <span class="ruby-keyword">when</span> <span class="ruby-constant">Regexp</span>
      <span class="ruby-identifier">custom_proxies</span>
    <span class="ruby-keyword">when</span> <span class="ruby-keyword">nil</span>
      <span class="ruby-constant">TRUSTED_PROXIES</span>
    <span class="ruby-keyword">else</span>
      <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">union</span>(<span class="ruby-constant">TRUSTED_PROXIES</span>, <span class="ruby-identifier">custom_proxies</span>)
    <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
              </div>
            </div>
            
          </div>
                  
      <div class="sectiontitle">Instance Public methods</div>
      
        <div class="method">
          <div class="title method-title" id="method-i-call">
            
              <b>call</b>(env)
            
            <a href="RemoteIp.html#method-i-call" name="method-i-call" class="permalink">Link</a>
          </div>
          
          
            <div class="description">
              <p>Since the IP address may not be needed, we store the object here without
calculating the IP to keep from slowing down the majority of requests. For
those requests that do need to know the IP, the <a
href="RemoteIp/GetIp.html#method-i-calculate_ip">ActionDispatch::RemoteIp::GetIp#calculate_ip</a>
method will calculate the memoized client IP address.</p>
            </div>
          
          
          
          
          
            
            <div class="sourcecode">
              
              <p class="source-link">
                Source: 
                <a href="javascript:toggleSource('method-i-call_source')" id="l_method-i-call_source">show</a>
                
                  | <a href="https://github.com/rails/rails/blob/a8df5bdc5d3cd5ad21758d8e421130bc9518b1dd/actionpack/lib/action_dispatch/middleware/remote_ip.rb#L74" target="_blank" class="github_url">on GitHub</a>
                
              </p>
              <div id="method-i-call_source" class="dyn-source">
                <pre><span class="ruby-comment"># File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 74</span>
<span class="ruby-keyword">def</span> <span class="ruby-keyword ruby-title">call</span>(<span class="ruby-identifier">env</span>)
  <span class="ruby-identifier">env</span>[<span class="ruby-string">&quot;action_dispatch.remote_ip&quot;</span>] = <span class="ruby-constant">GetIp</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">env</span>, <span class="ruby-keyword">self</span>)
  <span class="ruby-ivar">@app</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">env</span>)
<span class="ruby-keyword">end</span></pre>
              </div>
            </div>
            
          </div>
                    </div>

    </div>
  </body>
</html>    